#ifndef EVENT_H_
#define EVENT_H_

#include <vector>

class GameState;
class GameEngine;
class LobbyState;
class Piece;
class Row;
class Well;
class Block;
class ClientMenuState;
class WellModel;
class MenuState;
class InputGameState;
class ServerMenuState;
class GamePlayState;
class ScoreModel;
class Score;
class GameOverState;
class PiecePreview;

class Event
{
public:
    Event();
    virtual ~Event();

    enum Id
    {
        CLIENT_DISCONNECTED = 0,
        CLIENT_CONNECTED,
        CLIENT_READY_TO_PLAY,
        CLIENT_MOVE_PIECE,

        SERVER_GAME_START,
        SERVER_GAME_OVER,
        SERVER_ADD_PIECE,
        SERVER_UPDATE_PIECE,
        SERVER_REMOVE_PIECE,
        SERVER_ADD_BLOCK_TO_ROW,
        SERVER_ADD_BLOCK_TO_PIECE,
        SERVER_UPDATE_BLOCK,
        SERVER_ADD_ROW,
        SERVER_MOVE_ROW,
        SERVER_REMOVE_ROW,
        SERVER_PLAYER_UPDATE,
        SERVER_ADD_SCORE_PLAYER,
        SERVER_UPDATE_SCORE,
        SERVER_UPDATE_PREVIEW,

        INTERNAL_SCORE = 100,
        INTERNAL_TEST
    };

    virtual GameState* visitMenuState(MenuState* menuState) const;
    virtual GameState* visitInputGameState(InputGameState* inputGameState) const;
    virtual GameState* visitLobbyState(LobbyState* lobbyState) const;
    virtual GameState* visitClientMenuState(ClientMenuState* clientMenuState) const;
    virtual GameState* visitGamePlayState(GamePlayState* gamePlayState) const;

    virtual void visitGameEngine(GameEngine* gameEngine) const;
    virtual void visitBlock(Block* block) const;
    virtual void visitPiece(Piece* piece) const;
    virtual void visitRow(Row* row) const;
    virtual void visitWell(Well* well) const;
    virtual void visitScore(Score* score) const;
    virtual void visitWellModel(WellModel* wellModel) const;
    virtual void visitScoreModel(ScoreModel* scoreModel) const;
    virtual void visitPiecePreview(PiecePreview* piecePreview) const;

};

typedef std::vector<Event*> Events;

#endif
